import React, { useState, useEffect, useRef } from 'react';
import { useHistory } from 'react-router-dom';
import Search from 'antd/lib/input/Search';
import { Button, Table, Modal, message, Upload, Progress, Tooltip, Dropdown, Menu } from 'antd';
import {
  getRobots,
  deleteRobot,
  uploadRobot,
  downloadRobot,
  getRobotInfo,
  confirmUploadRobot,
  offVersion,
  onVersion,
} from 'admin/servers/servers';
import { RobotInfo } from 'admin/schema/Robots';
import { ColumnsType } from 'antd/lib/table';
import moment from 'moment';
import { clearNull, deleteRowChangePageNum } from 'utils/tools';
import './style.scss';
import { DownOutlined } from '@ant-design/icons';
import { debounce } from 'lodash';
import { VersionStatus } from 'admin/schema/RobotVersion';
import { useDispatch, useSelector } from 'react-redux';
import { JSONObject } from 'admin/schema/common';
import produce from 'immer';

import { robotAction } from 'store/robot';
import { intentionAction } from 'store/intention';
import { questionAction } from 'store/question';
import RobotPop from './components/RobotPop';
import RobotDetail from './components/RobotDetail';

const Robots: React.FC = () => {
  const history = useHistory();

  // 数据总数
  const [total, setTotal] = useState<number>(0);
  // Table loading状态
  const [tableLoading, setTableLoading] = useState<boolean>(false);
  const [tableData, setTableData] = useState<RobotInfo[]>([]);

  // 新建机器人：弹框显示
  const [editVisible, setEditVisible] = useState(false);
  const [detailData, setDetailData] = useState<RobotInfo>({} as any);
  const [detailVisible, setDetailVisible] = useState(false);
  // 删除机器人：弹框显示
  const [deleteVisible, setDeleteVisible] = useState<boolean>(false);
  // 删除机器人：机器人ID
  const [deleteRobotId, setDeleteRobotId] = useState<number>(0);
  // 删除机器人：确认按钮loading
  const [confirmDeleteLoading, setConfirmDeleteLoading] = useState<boolean>(false);

  // 机器人：上传文件
  const [uploadFile, setUploadFile] = useState<any>(undefined);
  // 页面卸载标志：true-卸载
  const isUnmount = useRef<any>(undefined);
  // 导入机器人
  const timer = useRef<any>(undefined); // 刷新列表，显示导入进度计时器
  /**查询缓存信息 */
  const { searchForm, robotFlowId } = useSelector((state: JSONObject) => state.robotList);
  const dispatch = useDispatch();

  // 操作列渲染
  const renderOperation = (text: any, record: RobotInfo) => {
    const { importStatus = 0, progressFinishedNumber, progressTotalNumber } = record;
    let percent = 0;
    if (importStatus > 0) {
      percent = Math.floor(
        (progressFinishedNumber && progressTotalNumber
          ? progressFinishedNumber / progressTotalNumber
          : 0) * 100
      );
    }
    switch (importStatus) {
      // 导入就绪
      case 1:
        return (
          <div className="progress-wrap">
            <div className="tip tip-loading">就绪</div>
            <Progress percent={percent} size="small" />
          </div>
        );
        break;
      // 导入中
      case 2:
        return (
          <div className="progress-wrap">
            <div className="tip tip-loading">导入中</div>
            <Progress percent={percent} size="small" />
          </div>
        );
        break;
      // 导入失败（删除）
      case 3:
        return (
          <div className="progress-wrap">
            <Tooltip title={record.errorReason}>
              <div className="tip tip-error">导入失败</div>
              <Progress percent={percent} size="small" status="exception" />
            </Tooltip>
            <Button type="link" onClick={() => deleteRobotAction(record)}>
              删除
            </Button>
          </div>
        );
        break;
      // 导入成功（确定）
      case 4:
        return (
          <div className="progress-wrap">
            <div className="tip tip-success">导入成功</div>
            <Progress percent={100} size="small" />
            <Button type="link" onClick={() => confirmRobotAction(record)}>
              确定
            </Button>
          </div>
        );
        break;
      // 0-正常
      case 0:
      default:
        return (
          <div>
            <Button
              type="link"
              size="small"
              onClick={() => {
                const { robotId } = record;
                if (robotFlowId !== robotId) {
                  // 更新缓存【配置流程】唯一标识
                  dispatch(robotAction.setRobotFlowId(robotId));
                  // 清除【意图库】【问答库】缓存
                  dispatch(intentionAction.resetSearchForm());
                  dispatch(questionAction.resetSearchForm());
                }
                // 流程配置-新版入口
                history.push(`/webapp/outbound/ai/robots/version/flow?robotId=${robotId}`);
              }}
            >
              配置话术流程
            </Button>
            <Button
              type="link"
              size="small"
              onClick={debounce(() => updateVersionStatus(record), 1000)}
            >
              {record.versionStatus === 'online' ? '下线' : '上线'}
            </Button>
            <Dropdown
              placement="bottomCenter"
              arrow
              overlayClassName="drop-menu-wrap"
              overlay={
                <Menu>
                  <Menu.Item key="0">
                    <Button type="link" onClick={() => handleEdit(record)}>
                      编辑
                    </Button>
                  </Menu.Item>
                  <Menu.Item key="1">
                    <Button type="link" onClick={() => handleDetail(record)}>
                      详情
                    </Button>
                  </Menu.Item>
                  <Menu.Item key="2">
                    <Button type="link" onClick={() => handleDownload(record)}>
                      导出
                    </Button>
                  </Menu.Item>
                  <Menu.Item key="3">
                    <Button type="link" onClick={() => deleteRobotAction(record)}>
                      删除
                    </Button>
                  </Menu.Item>
                </Menu>
              }
              trigger={['click']}
            >
              <a className="ant-dropdown-link" onClick={e => e.preventDefault()}>
                更多 <DownOutlined />
              </a>
            </Dropdown>
          </div>
        );
        break;
    }
  };
  // 机器人管理每列配置
  const columns: ColumnsType<RobotInfo> = [
    {
      title: '序号',
      dataIndex: 'key',
      align: 'center',
      key: 'key',
      fixed: 'left',
      render: (text, record, index) => index + 1 + searchForm.pageSize * (searchForm.pageNo - 1),
      width: 70,
    },
    {
      title: '机器人名称',
      dataIndex: 'robotName',
      key: 'robotName',
      ellipsis: true,
    },
    {
      title: '机器人标识',
      dataIndex: 'robotFlag',
      key: 'robotFlag',
      ellipsis: true,
    },
    {
      title: '创建人',
      dataIndex: 'userName',
      key: 'userName',
      ellipsis: true,
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      key: 'createTime',
      render: text => {
        return moment(Number(text)).format('YYYY-MM-DD HH:mm');
      },
      width: 180,
    },
    {
      title: '状态',
      dataIndex: 'versionStatus',
      key: 'versionStatus',
      width: 120,
      render: text => {
        switch (text) {
          case 'draft':
            return VersionStatus.draft;
          case 'online':
            return VersionStatus.online;
          case 'offline':
            return VersionStatus.offline;
          default:
            return '';
        }
      },
    },
    {
      title: '操作',
      key: 'operation',
      width: 250,
      fixed: 'right',
      render: renderOperation,
    },
  ];
  /**开启定时器 */
  function startTimer() {
    if (timer.current) {
      return;
    }
    // 条件：开启定时1s刷新进度
    timer.current = setInterval(() => {
      getTableData();
    }, 1000);
    console.log('>>>>>>>>>>>启动定时器', timer.current);
  }
  /**清除定时器 */
  function clearTimer() {
    if (!timer.current) {
      return;
    }
    console.log('=============清除定时器', timer.current);
    clearInterval(timer.current);
    timer.current = null;
  }
  /**请求列表接口数据 */
  const getTableData = async (showLoading?: boolean) => {
    showLoading && setTableLoading(true);
    const { pageNo, pageSize, searchText } = searchForm;
    console.log(searchForm, '查询条件===请求列表接口数据');
    try {
      const { data, count } = await getRobots(
        clearNull({
          pageNo,
          pageSize,
          robotName: searchText,
        })
      );
      console.log('getTableData -> res', data, count);
      if (isUnmount.current) {
        console.log('页面已经卸载end');
        return;
      }
      setTableData(data || []);
      setTotal(Number(count) || 0);
    } catch (error) {
      console.error(`系统异常: ${JSON.stringify(error)}`);
      clearTimer();
    }
    showLoading && setTableLoading(false);
  };

  // 更新页面，清理定时器
  useEffect(() => {
    console.log('**************页面初始化 init');
    isUnmount.current = false;
    return () => {
      console.log('==============页面卸载 leave');
      clearTimer();
      // 卸载中
      isUnmount.current = true;
    };
  }, []);

  // 数据初始化 && 数据更新
  useEffect(() => {
    console.log('update table data ✅');
    getTableData(true);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [searchForm]);

  useEffect(() => {
    clearTimer();
    // 在当前页查找，如果没有待导入和导入中状态的数据，则停止计时器
    const loadingRobots = tableData.filter(
      value => value.importStatus === 1 || value.importStatus === 2
    );
    if (loadingRobots.length) {
      console.log('check robots progress');
      startTimer();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [tableData]);

  /**
   * 翻页、每页条数
   * @param pageNo 点击页码
   * @param pageSize 点击每页条数
   */
  const onChangePage = (pageNo: number, pageSize?: number) => {
    console.log('搜索条件变更***页码+条数', pageNo, pageSize);
    const data: any = produce(searchForm, (draft: any) => {
      draft.pageNo = pageNo;
      if (pageSize) {
        draft.pageSize = pageSize;
      }
    });
    dispatch(robotAction.setSearchForm(data));
  };

  /**
   * 根据机器人名称搜索
   * @param text 搜索内容
   */
  const handleSearch = (text: string) => {
    console.log('搜索条件变更***机器人名称', text);
    const data: any = produce(searchForm, (draft: any) => {
      draft.searchText = text.trim();
      draft.pageNo = 1;
    });
    dispatch(robotAction.setSearchForm(data));
  };
  /**
   * 对列表数据进行刷新：新增，编辑
   * @param pageNum 最新页码
   */
  const refreshTable = async (newPageNum?: number) => {
    if (newPageNum && newPageNum !== searchForm.pageNo) {
      // 刷新到最新页码
      onChangePage(newPageNum);
    } else {
      // 刷新当前页面，页码不变
      getTableData(true);
    }
  };

  /**
   * 对table数据进行刷新：删除
   */
  function deleteFresh(size: number) {
    const newPageNum = deleteRowChangePageNum(size, total, searchForm.pageNo, searchForm.pageSize);
    refreshTable(newPageNum);
  }

  /**
   * 新增操作
   */
  const handleAdd = () => {
    setEditVisible(true);
  };

  /**
   * 编辑操作
   * @param robotId
   */
  const handleEdit = async ({ robotId }: RobotInfo) => {
    try {
      // 获取机器人数据
      const { data } = await getRobotInfo({ robotId });
      setEditVisible(true);
      setDetailData(data as any);
    } catch (error) {
      console.error(`系统异常: ${JSON.stringify(error)}`);
    }
  };

  /**
   * 详情操作
   * @param robotId
   */
  const handleDetail = async ({ robotId }: RobotInfo) => {
    try {
      const { data } = await getRobotInfo({ robotId });
      setDetailVisible(true);
      setDetailData(data);
    } catch (error) {
      console.error(`系统异常: ${JSON.stringify(error)}`);
    }
  };

  /**
   * 确定操作（导入100%时）
   * @param record 确定数据
   */
  const confirmRobotAction = async (record: RobotInfo) => {
    try {
      await confirmUploadRobot(record.robotId);
      message.success('机器人导入成功');
      refreshTable(1);
    } catch (error) {
      console.error(`系统异常: ${JSON.stringify(error)}`);
    }
  };

  /**
   * 删除操作
   * @param record 所删除数据
   */
  const deleteRobotAction = (record: RobotInfo) => {
    setDeleteRobotId(record.robotId);
    setDeleteVisible(true);
  };
  /**
   * 请求删除机器人接口
   * @param robotId
   */
  const requestDeleteRobot = async (robotId: number) => {
    setConfirmDeleteLoading(true);
    try {
      await deleteRobot(robotId);
      message.success('删除机器人成功');
      deleteFresh(1);
    } catch (error) {
      console.error(`系统异常: ${JSON.stringify(error)}`);
    }
    setDeleteVisible(false);
    setConfirmDeleteLoading(false);
  };

  /**
   * 机器人：上传前校验
   */
  const beforeUpload = (file: any): boolean => {
    const fileName = file.name.split('.');
    const type = file.type;
    const isRbt = (type && type.indexOf('rbt') > -1) || fileName[fileName.length - 1] === 'rbt';

    if (!isRbt) {
      message.error('请上传rbt文件（只支持rbt格式）!');
      return false;
    }

    setUploadFile(file);
    return true;
  };
  /**
   * 机器人：执行上传
   */
  const handleUpload = () => {
    const formData = new FormData();
    formData.append('file', uploadFile);
    console.log('开始上传', uploadFile);
    // 接口
    uploadRobot(formData)
      .then(res => {
        if (res.code === 0) {
          message.success('正在导入机器人，请稍候');
          refreshTable(1);
        } else {
          message.error(`${res.tips}(错误码: ${res.code})`);
        }
      })
      .catch(error => {
        console.error(`系统异常: ${JSON.stringify(error)}`);
      });
  };
  /**
   * 机器人：导出
   */
  const handleDownload = (record: RobotInfo) => {
    const { robotName, robotId } = record;

    // 接口
    downloadRobot(robotId)
      .then(data => {
        console.log(data, '下载');
        if (!data) {
          message.warning('文件下载失败');
          return;
        }
        const fileName = robotName;
        if (typeof (window.navigator as any).msSaveBlob !== 'undefined') {
          (window.navigator as any).msSaveBlob(
            new Blob([data], { type: 'text/plain' }),
            fileName + '.rbt'
          );
        } else {
          const url = window.URL.createObjectURL(new Blob([data], { type: 'text/plain' }));
          const link = document.createElement('a');
          link.style.display = 'none';
          link.href = url;
          link.setAttribute('download', fileName + '.rbt');
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link); // 下载完成移除元素
          window.URL.revokeObjectURL(url); // 释放掉blob对象
        }
      })
      .catch(() => {});
  };

  /**
   * 更新机器人状态：上线、下线操作
   */
  const updateVersionStatus = async ({ versionId, versionStatus }: RobotInfo) => {
    if (versionStatus === 'online') {
      // 1-上线状态，则请求接口进行【下线】
      try {
        await offVersion({
          versionId: versionId,
        });
        message.success(`下线成功`);
        refreshTable();
      } catch (error) {
        console.error(`系统异常: ${JSON.stringify(error)}`);
      }
    } else {
      // 2-草稿，下线，则请求接口进行【上线】
      try {
        await onVersion({
          versionId: versionId,
        });
        message.success(`上线成功`);
        refreshTable();
      } catch (error) {
        console.error(`系统异常: ${JSON.stringify(error)}`);
      }
    }
  };

  return (
    <div id="robotBox" className="page-more-btns">
      <div className="mgr-header">
        <div className="mgr-header-left">
          <Search
            placeholder="请输入机器人名称"
            enterButton="搜索"
            defaultValue={searchForm?.searchText}
            style={{ width: 300 }}
            onSearch={handleSearch}
            allowClear
          />
        </div>
        <div className="mgr-header-right">
          <div className="robot-button-container">
            <Button type="primary" onClick={handleAdd}>
              新建机器人
            </Button>
            <Upload
              name="file"
              accept=".rbt"
              showUploadList={false}
              multiple={false}
              beforeUpload={beforeUpload}
              customRequest={handleUpload}
            >
              <Button type="primary">导入</Button>
            </Upload>
          </div>
        </div>
      </div>
      <div className="mgr-table robots-list">
        <Table
          scroll={{ x: '100%', scrollToFirstRowOnChange: true }}
          loading={tableLoading}
          columns={columns}
          dataSource={tableData}
          rowKey="robotId"
          pagination={{
            total: total,
            showTotal: (total: number) => `共 ${total} 条`,
            current: searchForm.pageNo,
            pageSize: searchForm.pageSize,
            showSizeChanger: true,
            onChange: onChangePage,
          }}
        />
      </div>
      {editVisible && (
        <RobotPop
          visible={editVisible}
          formData={detailData}
          callBack={(flag: boolean) => {
            if (flag) {
              // 操作成功
              if (detailData.robotId) {
                // 编辑，刷新列表
                refreshTable();
              } else {
                // 新增，刷新到第一页
                refreshTable(1);
              }
            }
            setEditVisible(false);
            setDetailData({} as any);
          }}
        />
      )}
      <RobotDetail
        visible={detailVisible}
        formData={detailData}
        onClose={() => {
          setDetailVisible(false);
          setDetailData({} as any);
        }}
      />
      {/* 机器人弹框：删除 */}
      <Modal
        title="删除机器人提示"
        visible={deleteVisible}
        onOk={() => {
          requestDeleteRobot(deleteRobotId);
        }}
        confirmLoading={confirmDeleteLoading}
        onCancel={() => {
          setDeleteVisible(false);
        }}
      >
        <p>删除后无法恢复！确定删除吗？</p>
      </Modal>
    </div>
  );
};

export default Robots;
